home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * DESQview/X
- * BASIC TCP (STREAM) DAEMON
- *
- * The following code demonstrates the implementation of a basic stream
- * daemon under DESQview/X. Similar code may be used for daemons that are
- * managed by the DESQview/X Network Manager, are activated in response to
- * a requested connection by a remote host, and process input as streams.
- *
- * The basic methodology is as follows.
- *
- * - The DESQview/X Network Manager opens a 'listening' socket for the daemon
- * based upon the contents of the NETWORK\INETD.CFG file, and the DVPs in
- * the NETWORK subdirectory.
- *
- * - A connection is made to the socket, and the Network Manager 'accepts'
- * the connection.
- *
- * - The Network Manager instructs DESQview/X to load the appropriate
- * DVP for the daemon (from INETD.CFG).
- *
- * - The daemon is started and immediately requests information about the
- * new connection (the socket ID).
- *
- * - The daemon processes the connection in whatever manner it sees fit, and
- * closes the connection socket when finished.
- *
- *
- ******************************************************************************/
-
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys\time.h>
-
- #include <netdb.h>
- #include <netinet\in.h>
- #include <sys\socket.h>
- #include <sys\errno.h>
- #include <sys\ioctl.h>
-
-
- void chat(int s);
-
- extern int kbhit(void);
-
- void main(int argc, char *argv[])
- {
- int s;
-
- /* Daemon has been started by the Network Manager. Request the connection */
- /* information. The second parameter to so_daemon indicates that we wish */
- /* to wait for the connection information. If we wished to poll for the */
- /* next connection, we could simply specify FALSE in the second parameter. */
-
- printf("\n\nDESQview/X Sample STREAM Daemon.");
-
- while(1){
-
- printf("\n\nRetrieving next connection. Please wait.\n");
-
- s = so_daemon(argv,1);
-
- if(s < 0){
- printf("\nError: Unable to retrieve connection information.\n\n");
- break;
- }
-
- chat(s);
-
- so_close(s);
-
- }
- }
-
-
-
- /*****************************************************************************
- *
- * void chat(int session);
- *
- * The following code demonstrates some of the basic BSD4.3 socket I/O calls.
- * Basically, we poll for data on the socket, while allowing the user to
- * enter some text which we then send to our connection partner.
- *
- ******************************************************************************/
- void chat(int s)
- {
- struct timeval t; /* set to 0 to indicate polling */
- long nonBlocking = 1l;
- char recvBuff[100]; /* Buffer to receive data into */
- char sendBuff[100]; /* Buffer data sent from */
- unsigned long ioBit,readBit,writeBit; /* I/O bits for the socket */
- int bytes,i;
- char done;
-
- printf("\n\n-----------------------------------");
- printf("---------------------------------------------\n");
- printf("<Enter> - Send (blank line to end)\n\n");
-
- /* Set the I/O strategy for the socket to non-blocking. This will */
- /* force I/O calls to return immediately if there is nothing to */
- /* do. */
-
- ioctl(s,FIONBIO,(char *)&nonBlocking);
-
- /* Initialize the timeout for the select call to 0. This will */
- /* transform the call from a waiting call to a polling call. */
-
- memset(&t,0,sizeof(struct timeval));
-
- /* The select call takes pointers to bit arrays indicating which */
- /* sockets we are concerned about. Initialize the bit indicating */
- /* the current socket. */
-
- ioBit = (long)(1l << s);
-
- done = 0;
-
- while(!done){
-
- writeBit = readBit = ioBit;
-
- select(s + 1,(struct fd_set *)&readBit,(struct fd_set *)&writeBit,(struct fd_set *)NULL,&t); /* Get read/write status */
-
- /* If the 'read' bit is still set after the select call, one of */
- /* two things is indicated. Either the socket has been closed, */
- /* or there is data to read for the socket. */
-
- if(readBit & ioBit){
-
- bytes = recv(s,recvBuff,sizeof(recvBuff),0);
-
- switch(bytes){
- case 0: /* Normal close */
- printf("\n\nSession Terminated by Partner.\n\n");
- done = 1;
- break;
- case -1:
- if(errno != EWOULDBLOCK){ /* Abnormal close */
- printf("\n\nSession Terminated Abnormally on Read.\n\n");
- done = 1;
- }
- break;
- default:
- for(i = 0;i < bytes;i++) /* Got some data */
- printf("%c",recvBuff[i]);
- }
- } else {
-
- /* If the 'write' bit is set and a key has been hit, collect the */
- /* user data and send it to the connection partner. */
-
- if((writeBit & ioBit) && kbhit()){
-
- strcpy(sendBuff,"<");
- gets(sendBuff + 1);
-
- if(!strlen(sendBuff + 1)){
- done = 1;
- break;
- }
- strcat(sendBuff,">\n");
-
- bytes = send(s,sendBuff,strlen(sendBuff),0);
-
- if(bytes == -1 && errno != EWOULDBLOCK){ /* Error Occured */
- printf("\n\nSession Terminated Abnormally on Write.\n\n");
- done = 1;
- }
- }
- }
- }
- }
-
-